package com.neu.questionnaire_system.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.neu.questionnaire_system.beans.ResponseEntity;
import com.neu.questionnaire_system.entity.Choice;
import com.neu.questionnaire_system.entity.Cluster;
import com.neu.questionnaire_system.entity.Question;
import com.neu.questionnaire_system.entity.Questionnaire;
import com.neu.questionnaire_system.mapper.ChoiceMapper;
import com.neu.questionnaire_system.mapper.ClusterMapper;
import com.neu.questionnaire_system.mapper.QuestionMapper;
import com.neu.questionnaire_system.mapper.QuestionnaireMapper;
import com.neu.questionnaire_system.service.QuestionService;
import com.neu.questionnaire_system.service.QuestionnaireService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neu.questionnaire_system.util.Constants;
import com.neu.questionnaire_system.util.DateUtil;
import com.neu.questionnaire_system.util.MethodUtil;
import com.neu.questionnaire_system.util.UUIDGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xingle
 * @since 2022-10-31
 */
@Service
public class QuestionnaireServiceImpl extends ServiceImpl<QuestionnaireMapper, Questionnaire> implements QuestionnaireService {

    @Autowired
    private QuestionnaireMapper questionnaireMapper;
    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private QuestionServiceImpl questionService;
    @Autowired
    private ChoiceServiceImpl choiceService;

    @Autowired
    private ClusterMapper clusterMapper;


    /**
     * created by libo 创建问卷的具体细节，status为问卷状态，默认为0表示未开启 2022-11-8
     *
     * @param map 包含创建问卷用户的uid和问卷中所创建的题目，以及设置问卷的结束时间
     * @return 返回统一的对象
     */
    public ResponseEntity insertQuestionnaire(Map<String, Object> map) {
        ResponseEntity responseEntity = new ResponseEntity();
        String qid = UUIDGenerator.getOneUUID();
        List<Question> questions = MethodUtil.castList(map.get("questions"), Question.class);
        String start = DateUtil.getCurrentTimestamp();
        Timestamp startStamp = DateUtil.stringToSqlTimestamp(start);
        Map<String, Object> maps = new HashMap<>();
        maps.put("uid", map.get("uid"));
        Timestamp endStamp = DateUtil.stringToSqlTimestamp(map.get("end").toString());
        maps.put("start", startStamp);
        maps.put("end", endStamp);
        maps.put("qid", qid);
        maps.put("answeredCount", 0);
        maps.put("status", "0");
        maps.put("qname",map.get("qname").toString());
        int res = questionnaireMapper.insertQuestionnaire(maps);
        questionService.createQuestion(questions, qid);
        List<Question> questionList = questionMapper.selectQuestionByQid(qid);
        choiceService.createChoiceAboutQues(MethodUtil.castList(map.get("choices"), Choice.class), questionList);
        Map<String, Object> mapRes = new HashMap<>();
        mapRes.put("questionnaireOK", questionnaireMapper.findQuestionnaireByQid(qid));
        mapRes.put("questions", questionList);
        mapRes.put("choices", choiceService.findChoiceByIdList(questionMapper.selectQuestionIdByQid(qid)));
        responseEntity.setData(mapRes);
        if (res > 0) {
            responseEntity.setMessage(Constants.ADD_MESSAGE);
            responseEntity.setCode(Constants.SUCCESS_CODE);
        } else {
            responseEntity.setMessage(Constants.ADD_FAIL_MESSAGE);
            responseEntity.setCode(Constants.FAIL_CODE);
        }

        return responseEntity;
    }

    /**
     * created by libo 分页查询当前用户创建的所有的问卷
     *
     * @param uid 当前用户的uid
     * @return 返回统一的对象
     */
    public ResponseEntity findQuestionnaireByUid(String uid) {
        ResponseEntity responseEntity = new ResponseEntity();
        List<IPage<Questionnaire>> list = new ArrayList<>();
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", uid);
        int current = 1;
        long count = 0;
        while (count <= questionnaireMapper.selectCount(queryWrapper)) {
            IPage<Questionnaire> iPage = questionnaireMapper.selectQuestionnaire(new Page<>(current, Constants.PAGE_SIZE),uid);
            list.add(iPage);
            current++;
            count += iPage.getSize();
        }
        responseEntity.setData(list);
        responseEntity.setCode(Constants.SUCCESS_CODE);
        responseEntity.setMessage(Constants.SELECT_MESSAGE);
        return responseEntity;
    }

    /**
     * created by libo 2022-11-8 需要获取问卷信息的功能，例如预览问卷等
     *
     * @param qid 需要访问信息的问卷qid
     * @return 返回封装问卷内容的对象
     */
    public ResponseEntity previewQuestionnaire(String qid) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> maps = new HashMap<>();
        maps.put("questionnaire", questionnaireMapper.findQuestionnaireByQid(qid));
        maps.put("questions", questionMapper.selectQuestionByQid(qid));
        maps.put("choices", choiceService.findChoiceByIdList(questionMapper.selectQuestionIdByQid(qid)));
        responseEntity.setData(maps);
        responseEntity.setMessage(Constants.SELECT_MESSAGE);
        responseEntity.setCode(Constants.SUCCESS_CODE);
        return responseEntity;
    }

    /**
     * created by libo 个性化组卷
     *
     * @param map 带有个性化组卷信息以及该问卷的qid
     * @return 返回统一的对象
     */
    public ResponseEntity individualization(Map<String, Object> map) {
        ResponseEntity responseEntity = new ResponseEntity();
        responseEntity.setCode(Constants.SUCCESS_CODE);
        responseEntity.setMessage(Constants.ADD_MESSAGE);
        Cluster cluster = clusterMapper.selectCidByKind(map.get("answerGroup").toString(),map.get("uid").toString());
        int res2 = clusterMapper.updateByKind(cluster.getCid(),map.get("qid").toString());
        int res = questionnaireMapper.individualizationQues(map);
        responseEntity.setData(res+res2);
        return responseEntity;
    }

    public ResponseEntity showQuestionnaire() {
        List<Questionnaire> list = questionnaireMapper.showQuestionnaire();
        ResponseEntity re = new ResponseEntity();
        if (list != null) {
            re.setCode(Constants.SUCCESS_CODE);
            re.setMessage(Constants.SELECT_MESSAGE);
            re.setData(list);
        } else {
            re.setCode(Constants.FAIL_CODE);
            re.setMessage(Constants.SELECT_FAIL_MESSAGE);
        }
        return re;
    }

    /**
     * created by libo 问卷删除重构，删除问卷后连带删除选项和题目，只能删除未开启状态的即status=0
     *
     * @param map 需要删除的问卷的qid
     * @return 返回统一的对象
     */
    public ResponseEntity deleteQuestionnaire(Map<String, Object> map) {

        ResponseEntity responseEntity = new ResponseEntity();
        String qid = map.get("qid").toString();
        int res = questionnaireMapper.deleteQuestionnaire(qid, "0");
        responseEntity.setData(res);
        if (res > 0) {
            int res1 = choiceService.deleteChoiceAboutQues(questionMapper.selectQuestionIdByQid(qid));
            if (res1 > 0) {
                int res2 = questionMapper.deleteQuestionAll(qid);
                if (res2 > 0) {
                    responseEntity.setMessage(Constants.DELETE_MESSAGE);
                    responseEntity.setCode(Constants.SUCCESS_CODE);
                }
            }
        } else {
            responseEntity.setMessage(Constants.QUESTIONNAIRE_DELETE_MESSAGE);
            responseEntity.setCode(Constants.FAIL_CODE);
        }
        return responseEntity;
    }

    /**
     * created by libo 发布问卷，同时调整问卷状态，默认已开启问卷可以直接发布，未开启问卷发布后状态改为发布
     *
     * @param map 包含问卷的qid
     * @return 返回统一的对象
     */
    public ResponseEntity publish(Map<String, Object> map) {
        ResponseEntity responseEntity = new ResponseEntity();
        String qid = map.get("qid").toString();
        Questionnaire questionnaire = questionnaireMapper.findQuestionnaireByQid(qid);
        if(questionnaire.getAnswerGroup() == "null"||questionnaire.getAnswerCount() == 0){
            responseEntity.setCode(Constants.FAIL_CODE);
            responseEntity.setMessage(Constants.FAIL_PUBLISH_MESSAGE);
            return responseEntity;
        }else if ("1".equals(questionnaire.getStatus())) {
            responseEntity.setCode(Constants.SUCCESS_CODE);
            responseEntity.setMessage(Constants.QUESTIONNAIRE_PUBLISH_MESSAGE);
        } else {
            String status = "1";
            int res = questionnaireMapper.updateQuestionnaireStatus(status, qid);
            if (res > 0) {
                responseEntity.setCode(Constants.SUCCESS_CODE);
                responseEntity.setMessage(Constants.QUESTIONNAIRE_PUBLISH_MESSAGE);
            }
        }
        return responseEntity;
    }

    /**
     * created by libo 模糊查询问卷
     * @param map 问卷搜索名
     * @return 统一返回对象
     */
    public ResponseEntity findQuestionnaireById(Map<String,Object> map) {
        ResponseEntity responseEntity = new ResponseEntity();
        List<IPage<Questionnaire>> list = new ArrayList<>();
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.like("qname", map.get("qname").toString());
        queryWrapper.eq("uid",map.get("uid").toString());
        int current = 1;
        long count = 0;
        while (count <= questionnaireMapper.selectCount(queryWrapper)) {
            IPage<Questionnaire> iPage = questionnaireMapper.selectPage(new Page<>(current,Constants.PAGE_SIZE),queryWrapper);
            list.add(iPage);
            current++;
            count += iPage.getSize();
        }
        responseEntity.setData(list);
        responseEntity.setCode(Constants.SUCCESS_CODE);
        responseEntity.setMessage(Constants.SELECT_MESSAGE);
        return responseEntity;
    }

    public ResponseEntity selectQuestionnaireDetail(){
        ResponseEntity response = new ResponseEntity();
        List<Map<String,Object>> result = questionnaireMapper.selectQuestionnaireDetail();
        response.setData(result);
        if(result==null){
            response.setCode(Constants.FAIL_CODE);
            response.setMessage(Constants.SELECT_FAIL_MESSAGE);
        }else{
            response.setCode(Constants.SUCCESS_CODE);
            response.setMessage(Constants.SELECT_MESSAGE);
        }
        return response;
    }

    /**
     * created by libo 动态修改问卷状态
     * @param map 包含问卷qid和问卷状态
     * @return 统一对象
     */
    public ResponseEntity updateQuestionnaireStatus(Map<String,Object> map){
        ResponseEntity responseEntity = new ResponseEntity();
        int res = questionnaireMapper.updateQuestionnaireStatus(map.get("status").toString(),map.get("qid").toString());
        responseEntity.setCode(Constants.SUCCESS_CODE);
        responseEntity.setMessage(Constants.UPDATE_MESSAGE);
        return responseEntity;
    }

    public boolean isQuestionnaireOpen(String qid){
        String status = questionnaireMapper.isQuestionnaireOpenByQid(qid);
        return !status.equals("0");
    }

    public int updateCount(String qid){
        Questionnaire questionnaire = questionnaireMapper.findQuestionnaireByQid(qid);
        int count = questionnaire.getAnsweredCount();
        if (count<questionnaire.getAnswerCount()){
            int res = questionnaireMapper.updateQuestionnaireCount(count+1,qid);
            return res;
        }else {
            return -1;
        }
    }

    public Questionnaire selectByQid(String qid){
        return questionnaireMapper.findQuestionnaireByQid(qid);
    }
}
